/** 放大镜*/
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import img1 from "@/assets/imgs/1.jpg"


export default function Canvas() {
  const frame = useRef<any>(null)
  const canvasDom = useRef<any>(null)
  const magnifyCanvasDom = useRef<any>(null)
  const canvasCtx = useRef<any>(null)
  const magnifyCanvasCtx = useRef<any>(null)
  const magnifyingGlassSize = useRef(40)

  const [top, setTop] = useState(0);
  const [left, setLeft] = useState(0);

  const initLocation = useRef<any>({
    x: 0,
    y: 0,
    minX: 0,
    maxX: 0,
    minY: 0,
    maxY: 0,
    size: 0,
  })


  const setInitPointer = useCallback(() => {
    let info = canvasDom.current.getBoundingClientRect()

    initLocation.current = {
      x: info.x,
      y: info.y,
      minX: info.x,
      maxX: info.x + info.width - magnifyingGlassSize.current,
      minY: info.y,
      maxY: info.y + info.height - magnifyingGlassSize.current,
    }

  }, [])

  /** 初始化，渲染图片*/
  useEffect(() => {
    if (canvasDom.current == null) {
      return
    }
    canvasCtx.current = (canvasDom.current).getContext('2d');
    magnifyCanvasCtx.current = (magnifyCanvasDom.current).getContext('2d');
    setInitPointer()
    let img = new Image();
    img.src = img1;
    img.onload = () => {
      const canvasWidth = canvasDom.current.width;
      const canvasHeight = canvasDom.current.height;
      const imageWidth = img.width;
      const imageHeight = img.height;
      const scale = Math.min(canvasWidth / imageWidth, canvasHeight / imageHeight);
      const scaledWidth = imageWidth * scale;
      const scaledHeight = imageHeight * scale;

      canvasCtx.current.drawImage(img, 0, 0, scaledWidth, scaledHeight)

      magnifyCanvasCtx.current.drawImage(
        canvasDom.current,
        0,
        0,
        magnifyingGlassSize.current,
        magnifyingGlassSize.current,
        0,
        0,
        300,
        300
      );
    }

    let scrollElement = (frame.current as any).closest('.scrollElement')
    const resizeObserver = new ResizeObserver(entries => {
      setInitPointer()
  });

    frame.current.addEventListener('mousemove', onMousemove)
    resizeObserver.observe(scrollElement);
    scrollElement.addEventListener('scroll', setInitPointer)

    return () => {
      frame.current && frame.current.removeEventListener('mousemove', onMousemove)
      resizeObserver.disconnect()
      scrollElement.removeEventListener('scroll', setInitPointer)
    }
  }, [])

  const onMousemove = useCallback((e: MouseEvent) => {
    let x = e.x;
    let y = e.y;

    let dataY = y - magnifyingGlassSize.current / 2;
    //判断边界
    if (dataY < initLocation.current.minY) {
      dataY = initLocation.current.minY
    } else if (dataY > initLocation.current.maxY) {
      dataY = initLocation.current.maxY
    }
    dataY = dataY - initLocation.current.y
    setTop(dataY)

    //判断边界
    let dataX = x - magnifyingGlassSize.current / 2;

    if (dataX < initLocation.current.minX) {
      dataX = initLocation.current.minX
    } else if (dataX > initLocation.current.maxX) {
      dataX = initLocation.current.maxX
    }
    dataX = dataX - initLocation.current.x
    setLeft(dataX)

    /** 切图*/
    magnifyCanvasCtx.current.drawImage(
      canvasDom.current,
      dataX,
      dataY,
      magnifyingGlassSize.current,
      magnifyingGlassSize.current,
      0, 0,
      300, 300
    );
  }, [])

  return (
    <>
      <div ref={frame} style={{
        display: 'inline-block',
        position: 'relative',
      }}>
        <canvas
          className='glass'
          ref={canvasDom} width={300} height={300}>
        </canvas>

        <div
          style={{
            position: 'absolute',
            zIndex: 0,
            top,
            left,
            width: `${magnifyingGlassSize.current}px`,
            height: `${magnifyingGlassSize.current}px`,
            background: 'yellow',
            opacity: '.2'
          }}>
        </div>
      </div>

      <canvas
        ref={magnifyCanvasDom} width={300} height={300}>
      </canvas>
    </>
  )
}